package com.cloudvane.ossc.system;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

import com.cloudvane.ossc.AccessControlEnum;
import com.cloudvane.ossc.ICloudStorageProxy;
import com.cloudvane.ossc.infrastructure.CloudDirectory;
import com.cloudvane.ossc.infrastructure.CloudObject;

public class LocalClient implements ICloudStorageProxy {

	private HashMap<String, String> settings;
	private String baseDirectory;
	
	public LocalClient() {
		settings = new HashMap<String, String>();
	}
	
	@Override
	public String getStorageClient() {
		return "Local File System";
	}

	@Override
	public List<CloudDirectory> listDirectories() {
		List<CloudDirectory> retval = new LinkedList<CloudDirectory>();
		File directory = new File(getDirectory());
		
		String[] dirs = directory.list(new FilenameFilter() {
			  @Override
			  public boolean accept(File dir, String name) {
			    return new File(dir, name).isDirectory();
			  }
			});
		
		for(String dir : dirs) {
			CloudDirectory cd = new CloudDirectory();
			cd.setAccessControl(AccessControlEnum.Public);
			cd.setDirectoryName(dir);
			retval.add(cd);
		}
		
		return retval;
	}

	@Override
	public List<CloudObject> listObjectsInDirectory(CloudDirectory directory) {
		List<CloudObject> retval = new LinkedList<CloudObject>();
		File maindirectory = new File(getDirectory() + File.separator + directory.getDirectoryName());
		
		for(File f : maindirectory.listFiles()) {
			CloudObject co = new CloudObject();
			co.setAccessControl(AccessControlEnum.Public);
			co.setFileName(f.getName());
			co.setDirectoryName(maindirectory.getAbsolutePath() + File.separator);
			retval.add(co);
		}
		
		return retval;
	}

	@Override
	public void createDirectory(CloudDirectory directory) {
		File dir = new File(getDirectory(directory));
		
		dir.mkdir();
	}

	@Override
	public void createObject(CloudDirectory targetDirectory, CloudObject object) {
		try {
			OutputStream outFile = new FileOutputStream(getFilename(targetDirectory, object));
			byte[] buffer = new byte[4096];  
			int bytesRead;  
			while ((bytesRead = object.getCloudObject().read(buffer)) != -1) {  
				outFile.write(buffer, 0, bytesRead);  
			}  
			object.getCloudObject().close();  
			outFile.close();
		} catch (FileNotFoundException e) {
			
			e.printStackTrace();
		} catch (IOException ioex) {
			ioex.printStackTrace();
		}
	}

	@Override
	public void addConfigSetting(String key, String value) {
		settings.put(key, value);
	}

	@Override
	public boolean isInitialized() {
		return true;
	}
	
	private String getDirectory() {
		String retval = LocalClient.class.getProtectionDomain().getCodeSource().getLocation().getPath();
		
		retval += File.separator;
		
		if(settings.containsKey("Path"))
			retval += settings.get("Path");
		
		retval = retval.replace("%20", " ");
		
		return retval + File.separator;
	}
	
	private String getDirectory(CloudDirectory combined) {
		String retval = getDirectory();
		retval += File.separator + combined.getDirectoryName() + File.separator;
		return retval;
	}
	
	private String getFilename(CloudDirectory dir, CloudObject file) {
		String retval = getDirectory(dir);
		retval += File.separator + file.getFileName();
		return retval;
	}

	@Override
	public InputStream getObject(CloudObject file) {
		try {
			return new FileInputStream(file.getDirectoryName() + file.getFileName());
		} catch (FileNotFoundException e) {
			return null;
		}
	}

	@Override
	public InputStream getObject(String file) {
		try {
			return new FileInputStream(file);
		} catch (FileNotFoundException e) {
			return null;
		}
	}

	@Override
	public void deleteObject(CloudObject file) {
		File todel = new File(file.getDirectoryName() + file.getFileName());
		
		todel.delete();
		
	}

	@Override
	public void deleteDirectory(CloudDirectory dir) {
		File todel = new File(getDirectory() + File.separator + dir.getDirectoryName());
		
		todel.delete();
	}

	@Override
	public String getFullPath(CloudDirectory dir) {
		return this.getDirectory(dir);
	}

	@Override
	public String getFullPath(CloudDirectory dir, CloudObject obj) {
		return this.getFilename(dir, obj);
	}

}
